const MapValues = require('../template')

console.log("=== MapValues 高级方法测试 ===")

// 测试深度映射值
console.log(
  "深度映射值:", (() => {
    const obj = { a: { b: { c: 1 } }, d: { e: 2 } }
    const mapped = MapValues.mapValuesDeep(obj, (value, key) => {
      if (typeof value === 'object' && !Array.isArray(value)) {
        return { ...value, processed: true }
      }
      return value * 2
    }, 2)

    return typeof mapped === 'object' &&
      typeof mapped.a === 'object' &&
      mapped.a.b.c === 2 &&
      mapped.a.processed === true &&
      typeof mapped.d === 'object' &&
      mapped.d.e === 4 &&
      mapped.d.processed === true
  })()
)

// 测试条件映射值
console.log(
  "条件映射值:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4 }
    const mapped = MapValues.mapValuesWithCondition(obj, (value, key) => value * 2, (value, key) => value > 2)

    return typeof mapped === 'object' &&
      mapped.a === 1 &&
      mapped.b === 2 &&
      mapped.c === 6 &&
      mapped.d === 8
  })()
)

// 测试类型映射值
console.log(
  "类型映射值:", (() => {
    const obj = { a: 1, b: 'test', c: true, d: 2 }
    const mapped = MapValues.mapValuesWithType(obj, (value, key) => value * 2, 'number')

    return typeof mapped === 'object' &&
      mapped.a === 2 &&
      mapped.b === 'test' &&
      mapped.c === true &&
      mapped.d === 4
  })()
)

// 测试键映射值
console.log(
  "键映射值:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const mapped = MapValues.mapValuesWithKey(obj, (value, key) => value * 2, (value, key) => key.toUpperCase())

    return typeof mapped === 'object' &&
      mapped.A === 2 &&
      mapped.B === 4 &&
      mapped.C === 6 &&
      !('a' in mapped) &&
      !('b' in mapped) &&
      !('c' in mapped)
  })()
)

// 测试正则映射值
console.log(
  "正则映射值:", (() => {
    const obj = { user_name: 'John', user_age: 30, admin_id: 1, admin_role: 'admin' }
    const mapped = MapValues.mapValuesWithPattern(obj, (value, key) => value.toString().toUpperCase(), /^user_/)

    return typeof mapped === 'object' &&
      mapped.user_name === 'JOHN' &&
      mapped.user_age === '30' &&
      mapped.admin_id === 1 &&
      mapped.admin_role === 'admin'
  })()
)

// 测试验证映射值
console.log(
  "验证映射值:", (() => {
    const obj = { name: 'John', age: 30, email: 'john@example.com' }
    const schema = {
      name: { type: 'string', required: true },
      age: { type: 'number', min: 0, max: 150 },
      email: { type: 'string', pattern: /@/ }
    }

    try {
      const mapped = MapValues.mapValuesWithValidation(obj, (value, key) => {
        if (key === 'name') return value.toUpperCase()
        if (key === 'age') return value + 1
        return value
      }, schema)
      return typeof mapped === 'object' &&
        mapped.name === 'JOHN' &&
        mapped.age === 31 &&
        mapped.email === 'john@example.com'
    } catch (error) {
      return false
    }
  })()
)

// 测试异步映射值
console.log(
  "异步映射值:", (() => {
    const obj = { a: 1, b: 'test' }

    return MapValues.mapValuesAsync(obj, (value, key) => {
      if (typeof value === 'string') return value.toUpperCase()
      return value * 2
    }, async (value, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      return value > 0
    }).then(mapped => {
      return typeof mapped === 'object' &&
        mapped.a === 2 &&
        mapped.b === 'TEST'
    }).catch(() => false)
  })()
)

// 测试并发映射值
console.log(
  "并发映射值:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4, e: 5 }

    return MapValues.mapValuesConcurrent(obj, (value, key) => value * 2, async (value, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      return value > 2
    }, 3).then(mapped => {
      return typeof mapped === 'object' &&
        mapped.a === 1 &&
        mapped.b === 2 &&
        mapped.c === 6 &&
        mapped.d === 8 &&
        mapped.e === 10
    }).catch(() => false)
  })()
)

// 测试统计映射值
console.log(
  "统计映射值:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const result = MapValues.mapValuesWithStats(obj, (value, key) => value * 2)

    return typeof result === 'object' &&
      typeof result.data === 'object' &&
      result.data.a === 2 &&
      result.data.b === 4 &&
      result.data.c === 6 &&
      typeof result.stats === 'object' &&
      result.stats.valuesMapped > 0
  })()
)

// 测试复杂嵌套结构映射值
console.log(
  "复杂嵌套结构映射值:", (() => {
    const obj = {
      user: {
        profile: {
          personal: {
            name: 'John',
            age: 30,
            address: {
              city: 'New York',
              country: 'USA'
            }
          },
          preferences: {
            theme: 'dark',
            language: 'en'
          }
        },
        posts: [
          { title: 'Post 1', likes: 10 },
          { title: 'Post 2', likes: 20 }
        ]
      },
      meta: { total: 2, page: 1 }
    }

    const mapped = MapValues.mapValues(obj, (value, key) => {
      if (typeof value === 'object' && !Array.isArray(value)) {
        return { ...value, processed: true }
      }
      if (Array.isArray(value)) {
        return value.map(item => ({ ...item, processed: true }))
      }
      return value
    })

    return typeof mapped === 'object' &&
      typeof mapped.user === 'object' &&
      mapped.user.processed === true &&
      typeof mapped.user.profile === 'object' &&
      mapped.user.profile.processed === true &&
      typeof mapped.user.profile.personal === 'object' &&
      mapped.user.profile.personal.processed === true &&
      mapped.user.profile.personal.name === 'John' &&
      mapped.user.profile.personal.age === 30 &&
      typeof mapped.user.profile.personal.address === 'object' &&
      mapped.user.profile.personal.address.processed === true &&
      mapped.user.profile.personal.address.city === 'New York' &&
      mapped.user.profile.personal.address.country === 'USA' &&
      typeof mapped.user.profile.preferences === 'object' &&
      mapped.user.profile.preferences.processed === true &&
      mapped.user.profile.preferences.theme === 'dark' &&
      mapped.user.profile.preferences.language === 'en' &&
      Array.isArray(mapped.user.posts) &&
      mapped.user.posts[0].title === 'Post 1' &&
      mapped.user.posts[0].likes === 10 &&
      mapped.user.posts[0].processed === true &&
      mapped.user.posts[1].title === 'Post 2' &&
      mapped.user.posts[1].likes === 20 &&
      mapped.user.posts[1].processed === true &&
      typeof mapped.meta === 'object' &&
      mapped.meta.processed === true &&
      mapped.meta.total === 2 &&
      mapped.meta.page === 1
  })()
)

// 测试数组路径映射值
console.log(
  "数组路径映射值:", (() => {
    const obj = { data: { items: [1, 2, 3] } }
    const mapped = MapValues.mapValues(obj, (value, key) => {
      if (Array.isArray(value)) {
        return value.map(x => x * 2)
      }
      return value
    })

    return typeof mapped === 'object' &&
      typeof mapped.data === 'object' &&
      Array.isArray(mapped.data.items) &&
      mapped.data.items[0] === 2 &&
      mapped.data.items[1] === 4 &&
      mapped.data.items[2] === 6
  })()
)

// 测试边界情况映射值
console.log(
  "边界情况映射值:", (() => {
    const obj = { '': 'empty key', ' ': 'space key', 'a': 'normal key' }
    const mapped = MapValues.mapValues(obj, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped[''] === 'EMPTY KEY' &&
      mapped[' '] === 'SPACE KEY' &&
      mapped.a === 'NORMAL KEY'
  })()
)

// 测试特殊字符映射值
console.log(
  "特殊字符映射值:", (() => {
    const obj = { 'key-with-dash': 'value1', 'key.with.dot': 'value2' }
    const mapped = MapValues.mapValues(obj, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped['key-with-dash'] === 'VALUE1' &&
      mapped['key.with.dot'] === 'VALUE2'
  })()
)

// 测试数字键映射值
console.log(
  "数字键映射值:", (() => {
    const obj = { 0: 'zero', 1: 'one', 2: 'two' }
    const mapped = MapValues.mapValues(obj, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped[0] === 'ZERO' &&
      mapped[1] === 'ONE' &&
      mapped[2] === 'TWO'
  })()
)

// 测试布尔值键映射值
console.log(
  "布尔值键映射值:", (() => {
    const obj = { true: 'yes', false: 'no' }
    const mapped = MapValues.mapValues(obj, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped.true === 'YES' &&
      mapped.false === 'NO'
  })()
)

// 测试原型链属性映射值
console.log(
  "原型链属性映射值:", (() => {
    function TestClass() {
      this.instanceProp = 'instance'
    }
    TestClass.prototype.prototypeProp = 'prototype'

    const instance = new TestClass()
    const mapped = MapValues.mapValues(instance, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped.instanceProp === 'INSTANCE' &&
      !('prototypeProp' in mapped)
  })()
)

// 测试Symbol键映射值
console.log(
  "Symbol键映射值:", (() => {
    const sym = Symbol('test')
    const obj = { [sym]: 'symbol value', normal: 'normal value' }
    const mapped = MapValues.mapValues(obj, (value, key) => value.toUpperCase())

    return typeof mapped === 'object' &&
      mapped[sym] === 'SYMBOL VALUE' &&
      mapped.normal === 'NORMAL VALUE'
  })()
)

// 测试复杂数组结构映射值
console.log(
  "复杂数组结构映射值:", (() => {
    const obj = {
      matrix: [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
      ]
    }
    const mapped = MapValues.mapValues(obj, (value, key) => {
      if (Array.isArray(value)) {
        return value.map(row => row.map(x => x * 2))
      }
      return value
    })

    return typeof mapped === 'object' &&
      Array.isArray(mapped.matrix) &&
      mapped.matrix[0][0] === 2 &&
      mapped.matrix[0][1] === 4 &&
      mapped.matrix[0][2] === 6 &&
      mapped.matrix[1][0] === 8 &&
      mapped.matrix[1][1] === 10 &&
      mapped.matrix[1][2] === 12 &&
      mapped.matrix[2][0] === 14 &&
      mapped.matrix[2][1] === 16 &&
      mapped.matrix[2][2] === 18
  })()
)

console.log("=== MapValues 高级方法测试完成 ===")

